use axum::{
    extract::Json,
    http::StatusCode,
    response::{IntoResponse, Response},
};
use serde_json::json;
use thiserror::Error;
use url::Url;

#[derive(Debug, Error)]
pub enum AppError {
    #[error("Axum error: `{0}`")]
    AxumError(#[from] axum::Error),
    #[error("Failed to connect to provider ws: `{0}`, err: `{1}`")]
    CannotConnectProvider(Url, tokio_tungstenite::tungstenite::Error),
    #[error("Invalid provider url: `{0}`")]
    InvalidProviderUrl(#[from] url::ParseError),
    #[error("Unsupported provider of: `{0}`")]
    UnsupportedProvider(String),
}

impl IntoResponse for AppError {
    fn into_response(self) -> Response {
        let code = match self {
            AppError::UnsupportedProvider(..) => StatusCode::BAD_REQUEST,
            _ => StatusCode::INTERNAL_SERVER_ERROR,
        };

        (
            code,
            Json(json!({"code": code.as_u16(), "message": self.to_string()})),
        )
            .into_response()
    }
}
